<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="../assets/css/yui-cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="shortcut icon" type="image/x-icon" href="../assets/favicon.ico">
    <script src="../assets/js/yui-source.js"></script>
	<title>TweenJS v1.0.0 API Documentation : tweenjs/plugins/CSSPlugin.js</title>
</head>
<body class="yui3-skin-sam">

<div id="doc">
    <div id="hd" class="yui3-g header">
        <div class="yui3-u-3-4">
            
                <h1><a href="http://createjs.site/tweenjs"><img src="../assets/docs-icon-TweenJS.png" title="TweenJS"></a></h1>
            
        </div>
        <div class="yui3-u-1-4 version">
            <em>API Documentation for: 1.0.0</em>
        </div>
    </div>
    <div id="bd" class="yui3-g">

        <div class="yui3-u-1-4">
            <div id="docs-sidebar" class="sidebar apidocs">
                <div id="api-list">
    <h2 class="off-left">APIs</h2>
    <div id="api-tabview" class="tabview">
        <ul class="tabs">
            <li><a href="#api-classes">Classes</a></li>
        </ul>

        <div id="api-tabview-filter">
            <input type="search" id="api-filter" placeholder="Type to filter APIs">
        </div>

        <div id="api-tabview-panel">
            <ul id="api-classes" class="apis classes">
            
                <li><a href="../classes/AbstractTween.html">AbstractTween</a></li>
            
                <li><a href="../classes/ColorPlugin.html">ColorPlugin</a></li>
            
                <li><a href="../classes/CSSPlugin.html">CSSPlugin</a></li>
            
                <li><a href="../classes/Ease.html">Ease</a></li>
            
                <li><a href="../classes/Event.html">Event</a></li>
            
                <li><a href="../classes/EventDispatcher.html">EventDispatcher</a></li>
            
                <li><a href="../classes/MotionGuidePlugin.html">MotionGuidePlugin</a></li>
            
                <li><a href="../classes/RelativePlugin.html">RelativePlugin</a></li>
            
                <li><a href="../classes/RotationPlugin.html">RotationPlugin</a></li>
            
                <li><a href="../classes/SamplePlugin.html">SamplePlugin</a></li>
            
                <li><a href="../classes/Ticker.html">Ticker</a></li>
            
                <li><a href="../classes/Timeline.html">Timeline</a></li>
            
                <li><a href="../classes/Tween.html">Tween</a></li>
            
                <li><a href="../classes/TweenJS.html">TweenJS</a></li>
            
                <li><a href="../classes/Utility Methods.html">Utility Methods</a></li>
            
            </ul>

            <ul id="api-modules" class="apis modules">
            
                <li><a href="../modules/CreateJS.html">CreateJS</a></li>
            
                <li><a href="../modules/EaselJS.html">EaselJS</a></li>
            
                <li><a href="../modules/TweenJS.html">TweenJS</a></li>
            
            </ul>
        </div>
    </div>
</div>

            </div>
        </div>
        <div class="yui3-u-3-4">
            <div id="api-options">
        Show:
        <label for="api-show-inherited">
            <input type="checkbox" id="api-show-inherited" checked>
            Inherited
        </label>

        <label for="api-show-protected">
            <input type="checkbox" id="api-show-protected">
            Protected
        </label>

        <label for="api-show-private">
            <input type="checkbox" id="api-show-private">
            Private
        </label>
        <label for="api-show-deprecated">
            <input type="checkbox" id="api-show-deprecated">
            Deprecated
        </label>

    </div>
            <div class="apidocs">
                <div id="docs-main">
                    <div class="content source-content">
                        <script>
	var name = tweenjs/plugins/CSSPlugin.js      
</script>
<h1 class="file-heading">File:CSSPlugin.js</h1>

<div class="file">
    <pre class="code prettyprint linenums">
/*
* CSSPlugin
* Visit http://createjs.site/ for documentation, updates and examples.
*
* Copyright (c) 2010 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the &quot;Software&quot;), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

/**
* @module TweenJS
*/

this.createjs = this.createjs||{};

(function() {
	&quot;use strict&quot;;

	/**
	 * A TweenJS plugin for working with numeric CSS string properties (ex. top, left). To use simply install after
	 * TweenJS has loaded:
	 *
	 * 	createjs.CSSPlugin.install();
	 *
	 * CSSPlugin works with almost any style property or unit. It identifies CSS values by looking for an initial value
	 * on the element&#x27;s &#x60;style&#x60; object. It also uses this initial value to parse out the units to use with that value.
	 * 
	 * In the following example, &#x60;top&#x60; would be tweened as a style using &#x60;em&#x60; units using CSSPlugin, but &#x60;width&#x60; 
	 * would be not be tweened as a style (because there is no initial inline style value for it).
	 *
	 * 	myEl.style.top = &quot;10em&quot;;
	 * 	createjs.Tween.get(myEl).to({top:20, width:100}, 1000);
	 *
	 * CSSPlugin can also use computed styles. Please see {{#crossLink &quot;AbstractTween/compute:property&quot;}}{{/crossLink}}
	 * for more information.
	 * 
	 * CSSPlugin has specific handling for the &#x60;transform&#x60; style, and will tween any transforms as long as their operations
	 * and units match. For example:
	 * 
	 * 	myEl.style.transform = &quot;translate(20px, 30px)&quot;;
	 * 	createjs.Tween.get(myEl)
	 * 		.to({transform: &quot;translate(40px, 50px)&quot;}, 900) // would be tweened, everything matches
	 * 		.to({transform: &quot;translate(5em, 300px)&quot;}, 900) // would NOT be tweened, different units (px vs em)
	 * 		.to({transform: &quot;scaleX(2)&quot;}, 900) // would NOT be tweened, different operations (translate vs rotate)
	 * 
	 * You can also use &#x60;*&#x60; to copy the operation at that position from the previous transform.
	 * 
	 * 	myEl.style.transform = &quot;translate(0px, 0px) rotate(0deg)&quot;;
	 * 	createjs.Tween.get(myEl)
	 * 		.to({transform: &quot;translate(50px, 50px) *&quot;}, 900) // would copy the &quot;rotate&quot; operation
	 * 		.to({transform: &quot;* rotate(90deg)&quot;}, 900) // would copy the &quot;translate&quot; operation
	 * 
	 * Please note that the CSS Plugin is not included in the TweenJS minified file.
	 * @class CSSPlugin
	 * @constructor
	 **/
	function CSSPlugin() {
		throw(&quot;CSSPlugin cannot be instantiated.&quot;)
	}
	var s = CSSPlugin;

// static properties
	/**
	 * @property priority
	 * @protected
	 * @static
	 **/
	s.priority = 100; // high priority, should read first and write last
	
	/**
	 * READ-ONLY. A unique identifying string for this plugin. Used by TweenJS to ensure duplicate plugins are not installed on a tween.
	 * @property ID
	 * @type {String}
	 * @static
	 * @readonly
	 **/
	s.ID = &quot;CSS&quot;;
	
	/**
	 * READ-ONLY.
	 * @property VALUE_RE
	 * @type {RegExp}
	 * @static
	 * @readonly
	 */
	s.VALUE_RE = /^(-?[\d.]+)([a-z%]*)$/; // extracts the numeric value and suffix from a single CSS value
	
	s.TRANSFORM_VALUE_RE = /(?:^| |,)(-?[\d.]+)([a-z%]*)/g; // extracts the numeric value and suffix from comma delimited lists
	
	s.TRANSFORM_RE = /(\w+?)\(([^)]+)\)|(?:^| )(\*)(?:$| )/g; // extracts the components of a transform
	
	
	
	/**
	 * By default, CSSPlugin uses only inline styles on the target element (ie. set via the style attribute, &#x60;style&#x60; property, or &#x60;cssText&#x60;)
	 * to determine which properties should be tweened via CSS, and what units to use.
	 * 
	 * Setting &#x60;compute&#x60; to &#x60;true&#x60; causes CSSPlugin to use &#x60;getComputedStyle&#x60; for this purpose. This has the advantage of
	 * including all styles that effect the target element, however there are some important considerations for its use:&lt;UL&gt;
	 * 	&lt;LI&gt; &#x60;getComputedStyle&#x60; is computationally expensive, which could lead to performance issues if you are creating a large
	 * 	number of tweens at once.
	 * 	&lt;LI&gt; styles are normalized. For example, a width value specified as a &#x60;%&#x60; may be computed as &#x60;px&#x60;, which CSSPlugin will
	 * 	use for the tween. Different browsers _may_ normalize values differently.
	 * 	&lt;LI&gt; there are a large number of computed styles, which increases the chance that a property will be identified as a style.
	 * 	&lt;LI&gt; does not work with IE8 or below.
	 * 	&lt;/UL&gt;
	 * 	
	 * 	The &#x60;compute&#x60; setting can be overridden on a per-tween basis by setting &#x60;tween.pluginData.CSS_compute&#x60;. For example,
	 * 	to enable computed styles for a new tween, you could use:
	 * 	
	 * 		createjs.Tween.get(el, {pluginData:{CSS_compute:true}}).to({top:20}, 1000);
	 * 	
	 * 	Given the considerations for &#x60;compute&#x60;, it is recommended that you keep the default global setting of &#x60;false&#x60; and override it
	 * 	in specific cases via &#x60;pluginData&#x60;.
	 * @property compute
	 * @type {Boolean}
	 * @default false
	 * @static
	 */
	s.compute = false;


// static methods
	/**
	 * Installs this plugin for use with TweenJS. Call this once after TweenJS is loaded to enable this plugin.
	 * @method install
	 * @static
	 **/
	s.install = function() {
		createjs.Tween._installPlugin(CSSPlugin);
	};

	/**
	 * Called by TweenJS when a new property initializes on a tween.
	 * See {{#crossLink &quot;SamplePlugin/init&quot;}}{{/crossLink}} for more info.
	 * @method init
	 * @param {Tween} tween
	 * @param {String} prop
	 * @param {any} value
	 * @return {any}
	 * @static
	 **/
	s.init = function(tween, prop, value) {
		var data = tween.pluginData;
		if (data.CSS_disabled || !(tween.target instanceof HTMLElement)) { return; }
		var initVal = value||getStyle(tween.target, prop, data.CSS_compute);
		if (initVal === undefined) { return;  }
		
		tween._addPlugin(CSSPlugin);
		var cssData = data.CSS || (data.CSS = {});
		if (prop === &quot;transform&quot;) {
			cssData[prop] = &quot;_t&quot;;
			return parseTransform(initVal);
		}
		
		var result = s.VALUE_RE.exec(initVal);
		if (result === null) {
			// a string we can&#x27;t handle numerically, so add it to the CSSData without a suffix.
			cssData[prop] = &quot;&quot;;
			return initVal;
		} else {
			cssData[prop] = result[2];
			return parseFloat(result[1]);
		}
	};

	
	/**
	 * Called when a new step is added to a tween (ie. a new &quot;to&quot; action is added to a tween).
	 * See {{#crossLink &quot;SamplePlugin/step&quot;}}{{/crossLink}} for more info.
	 * @method step
	 * @param {Tween} tween
	 * @param {TweenStep} step
	 * @param {Object} props
	 * @static
	 **/
	s.step = function(tween, step, props) {
		if (props.transform) {
			step.props.transform = parseTransform(step.props.transform, step.prev.props.transform);
		}
	};

	/**
	 * Called before a property is updated by the tween.
	 * See {{#crossLink &quot;SamplePlugin/change&quot;}}{{/crossLink}} for more info.
	 * @method change
	 * @param {Tween} tween
	 * @param {TweenStep} step
	 * @param {String} prop
	 * @param {any} value
	 * @param {Number} ratio
	 * @param {Boolean} end
	 * @return {any}
	 * @static
	 **/
	s.change = function(tween, step, prop, value, ratio, end) {
		var sfx = tween.pluginData.CSS[prop];
		if (sfx === undefined) { return; }
		if (prop === &quot;transform&quot;) {
			value = writeTransform(step.prev.props[prop], step.props[prop], ratio);
		} else {
			value += sfx;
		}
		tween.target.style[prop] = value;
		return createjs.Tween.IGNORE;
	};
	
	
// private helper methods:
	function getStyle(target, prop, compute) {
		if (compute || (compute == null &amp;&amp; s.compute)) {
			return window.getComputedStyle(target)[prop];
		} else {
			return target.style[prop];
		}
	}

	function parseTransform(str, compare) {
		var result, list = [false, str];
		do {
			// pull out the next &quot;component&quot; of the transform (ex. &quot;translate(10px, 20px)&quot;)
			result = s.TRANSFORM_RE.exec(str);
			if (!result) { break; }
			if (result[3] === &quot;*&quot;) {
				// reuse previous value:
				list.push(compare[list.length]);
				continue;
			}
			var component = [result[1]], compareComp = compare &amp;&amp; compare[list.length];
			
			// check that the operation type matches (ex. &quot;translate&quot; vs &quot;rotate&quot;):
			if (compare &amp;&amp; (!compareComp || component[0] !== compareComp[0])) { console.log(&quot;transforms don&#x27;t match: &quot;,component[0],compareComp[0]); compare=null; } // component doesn&#x27;t match
			
			parseMulti(result[2], compareComp, component);

			list.push(component);
		} while(true);

		list[0] = !!compare;
		return list;
	}
	
	// this was separated so that it can be used for other multi element styles in the future
	// ex. transform-origin, border, etc.
	function parseMulti(str, compare, arr) {
		// TODO: add logic to deal with &quot;0&quot; values? Troublesome because the browser automatically appends a unit for some 0 values.
		do {
			// pull out the next value (ex. &quot;20px&quot;, &quot;12.4rad&quot;):
			var result = s.TRANSFORM_VALUE_RE.exec(str);
			if (!result) { return arr; }
			if (!arr) { arr = []; }
			arr.push(+result[1], result[2]);

			// check that the units match (ex. &quot;px&quot; vs &quot;em&quot;):
			if (compare &amp;&amp; (compare[arr.length-1] !== result[2])) { console.log(&quot;transform units don&#x27;t match: &quot;,arr[0], compare[arr.length-1], result[2]); compare=null;  } // unit doesn&#x27;t match
		} while(true);
	}

	function writeTransform(list0, list1, ratio) {
		// check if we should just use the original transform strings:
		if (ratio === 1) { return list1[1]; }
		if (ratio === 0 || !list1[0]) { return list0[1]; }

		// they match, we want to apply the ratio:
		var str = &quot;&quot;, l=list0.length, i, j, jl;
		for (i=2; i&lt;l; i++) {
			var component0 = list0[i], component1 = list1[i];
			str += component0[0]+&quot;(&quot;;
			for (j=1, jl=component0.length; j&lt;jl; j+=2) {
				str += component0[j]+(component1[j]-component0[j])*ratio; // value
				str += component1[j+1] || component0[j+1]; // unit
				if (j &lt; jl-2) { str += &quot;, &quot;; }
			}
			str += &quot;)&quot;;
			if (i &lt; l-1) { str += &quot; &quot;; }
		}
		return str;
	}
	
	/*
	
	// this was part of an attempt to handle multi element css values, ex. margin=&quot;10px 10px 20px 30px&quot;
	// discarded because the browser likes to collapse values, which makes a generic solution infeasible.
	// for example, margin=&quot;10px 10px 10px 10px&quot; will collapse to just &quot;10px&quot;
	// requires custom logic to handle each scenario.
	s.MULTI_RE = /((?:^| )-?[\d.]+[a-z%]*){2,}/; // matches CSS values that consist of two or more values with suffixes
	function writeMulti(arr0, arr1, ratio) {
		var str = &quot;&quot;, l=arr0.length, i;
		for (i=0; i&lt;l; i+=2) {
			str += arr0[i]+(arr1[i]-arr0[i])*ratio+arr0[i+1];
			if (i &lt; l-2) { str += &quot; &quot;; }
		}
		return str;
	}
	
	// this method is really only needed for roundtrip tests.
	function writeSingleTransform(list) {
		var str = &quot;&quot;, l=list.length, i, j, jl, component;
		for (i=2; i&lt;l; i++) {
			component = list[i];
			str += component[0]+&quot;(&quot;;
			for (j=1, jl=component.length; j&lt;jl; j+=2) {
				str += component[j]+component[j+1];
				if (j &lt; jl-2) { str += &quot;, &quot;; }
			}
			str += &quot;)&quot;;
			if (i &lt; l-1) { str += &quot; &quot;; }
		}
		return str;
	}
	*/
	
	createjs.CSSPlugin = s;

}());

    </pre>
</div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>
